home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / gnu / gnulib / dkbtrace / pbmplus / source / ppm / ppmpat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-10  |  31.9 KB  |  1,088 lines

  1. /* ppmpat.c - make a pixmap
  2. **
  3. ** Copyright (C) 1989, 1991 by Jef Poskanzer.
  4. **
  5. ** Permission to use, copy, modify, and distribute this software and its
  6. ** documentation for any purpose and without fee is hereby granted, provided
  7. ** that the above copyright notice appear in all copies and that both that
  8. ** copyright notice and this permission notice appear in supporting
  9. ** documentation.  This software is provided "as is" without express or
  10. ** implied warranty.
  11. */
  12.  
  13. #include "ppm.h"
  14. #include "ppmdraw.h"
  15. #include <math.h>
  16. #ifndef M_PI
  17. #define M_PI    3.14159265358979323846
  18. #endif /*M_PI*/
  19.  
  20. static pixel random_color ARGS(( pixval maxval ));
  21. static pixel random_bright_color ARGS(( pixval maxval ));
  22. static pixel random_dark_color ARGS(( pixval maxval ));
  23. static pixel average_two_colors ARGS(( pixel p1, pixel p2 ));
  24. static void average_drawproc ARGS(( pixel** pixels, int cols, int rows, pixval maxval, int col, int row, char* clientdata ));
  25. static void gingham2 ARGS(( pixel** pixels, int cols, int rows, pixval maxval ));
  26. static void gingham3 ARGS(( pixel** pixels, int cols, int rows, pixval maxval ));
  27. static void madras ARGS(( pixel** pixels, int cols, int rows, pixval maxval ));
  28. static void tartan ARGS(( pixel** pixels, int cols, int rows, pixval maxval ));
  29. static void poles ARGS(( pixel** pixels, int cols, int rows, pixval maxval ));
  30. static void sq_measurecircle_drawproc ARGS(( pixel** pixels, int cols, int rows, pixval maxval, int col, int row, char* clientdata ));
  31. static void sq_rainbowcircle_drawproc ARGS(( pixel** pixels, int cols, int rows, pixval maxval, int col, int row, char* clientdata ));
  32. static void squig ARGS(( pixel** pixels, int cols, int rows, pixval maxval ));
  33. static void sq_assign_colors ARGS(( int circlecount, pixval maxval, pixel* colors ));
  34. static pixel random_camo_color ARGS(( pixval maxval ));
  35. static pixel random_anticamo_color ARGS(( pixval maxval ));
  36. static float rnduni ARGS(( void ));
  37. static void camo ARGS(( pixel** pixels, int cols, int rows, pixval maxval, int antiflag ));
  38. static void test ARGS(( pixel** pixels, int cols, int rows, pixval maxval ));
  39.  
  40. void
  41. main( argc, argv )
  42.     int argc;
  43.     char* argv[];
  44.     {
  45.     pixel** pixels;
  46.     int argn, pattern, cols, rows;
  47. #define PAT_NONE 0
  48. #define PAT_GINGHAM2 1
  49. #define PAT_GINGHAM3 2
  50. #define PAT_MADRAS 3
  51. #define PAT_TARTAN 4
  52. #define PAT_POLES 5
  53. #define PAT_SQUIG 6
  54. #define PAT_CAMO 7
  55. #define PAT_ANTICAMO 8
  56. #define PAT_TEST 9
  57.     char* usage = "-gingham|-g2|-gingham3|-g3|-madras|-tartan|-poles|-squig|-camo|-anticamo <width> <height>";
  58.  
  59.     ppm_init( &argc, argv );
  60.  
  61.     argn = 1;
  62.     pattern = PAT_NONE;
  63.  
  64.     while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
  65.     {
  66.     if ( pm_keymatch( argv[argn], "-gingham2", 9 ) ||
  67.          pm_keymatch( argv[argn], "-g2", 3 ) )
  68.         {
  69.         if ( pattern != PAT_NONE )
  70.         pm_error( "only one base pattern may be specified" );
  71.         pattern = PAT_GINGHAM2;
  72.         }
  73.     else if ( pm_keymatch( argv[argn], "-gingham3", 9 ) ||
  74.          pm_keymatch( argv[argn], "-g3", 3 ) )
  75.         {
  76.         if ( pattern != PAT_NONE )
  77.         pm_error( "only one base pattern may be specified" );
  78.         pattern = PAT_GINGHAM3;
  79.         }
  80.     else if ( pm_keymatch( argv[argn], "-madras", 2 ) )
  81.         {
  82.         if ( pattern != PAT_NONE )
  83.         pm_error( "only one base pattern may be specified" );
  84.         pattern = PAT_MADRAS;
  85.         }
  86.     else if ( pm_keymatch( argv[argn], "-tartan", 2 ) )
  87.         {
  88.         if ( pattern != PAT_NONE )
  89.         pm_error( "only one base pattern may be specified" );
  90.         pattern = PAT_TARTAN;
  91.         }
  92.     else if ( pm_keymatch( argv[argn], "-poles", 2 ) )
  93.         {
  94.         if ( pattern != PAT_NONE )
  95.         pm_error( "only one base pattern may be specified" );
  96.         pattern = PAT_POLES;
  97.         }
  98.     else if ( pm_keymatch( argv[argn], "-squig", 2 ) )
  99.         {
  100.         if ( pattern != PAT_NONE )
  101.         pm_error( "only one base pattern may be specified" );
  102.         pattern = PAT_SQUIG;
  103.         }
  104.     else if ( pm_keymatch( argv[argn], "-camo", 2 ) )
  105.         {
  106.         if ( pattern != PAT_NONE )
  107.         pm_error( "only one base pattern may be specified" );
  108.         pattern = PAT_CAMO;
  109.         }
  110.     else if ( pm_keymatch( argv[argn], "-anticamo", 2 ) )
  111.         {
  112.         if ( pattern != PAT_NONE )
  113.         pm_error( "only one base pattern may be specified" );
  114.         pattern = PAT_ANTICAMO;
  115.         }
  116.     else if ( pm_keymatch( argv[argn], "-test", 3 ) )
  117.         {
  118.         if ( pattern != PAT_NONE )
  119.         pm_error( "only one base pattern may be specified" );
  120.         pattern = PAT_TEST;
  121.         }
  122.     else
  123.         pm_usage( usage );
  124.     ++argn;
  125.     }
  126.     if ( pattern == PAT_NONE )
  127.     pm_error( "a base pattern must be specified" );
  128.  
  129.     if ( argn == argc )
  130.     pm_usage( usage);
  131.     if ( sscanf( argv[argn], "%d", &cols ) != 1 )
  132.     pm_usage( usage );
  133.     ++argn;
  134.     if ( argn == argc )
  135.     pm_usage( usage);
  136.     if ( sscanf( argv[argn], "%d", &rows ) != 1 )
  137.     pm_usage( usage );
  138.     ++argn;
  139.  
  140.     if ( argn != argc )
  141.     pm_usage( usage);
  142.  
  143.     srandom( (int) ( time( 0 ) ^ getpid( ) ) );
  144.     pixels = ppm_allocarray( cols, rows );
  145.  
  146.     switch ( pattern )
  147.     {
  148.     case PAT_GINGHAM2:
  149.     gingham2( pixels, cols, rows, PPM_MAXMAXVAL );
  150.     break;
  151.  
  152.     case PAT_GINGHAM3:
  153.     gingham3( pixels, cols, rows, PPM_MAXMAXVAL );
  154.     break;
  155.  
  156.     case PAT_MADRAS:
  157.     madras( pixels, cols, rows, PPM_MAXMAXVAL );
  158.     break;
  159.  
  160.     case PAT_TARTAN:
  161.     tartan( pixels, cols, rows, PPM_MAXMAXVAL );
  162.     break;
  163.  
  164.     case PAT_POLES:
  165.     poles( pixels, cols, rows, PPM_MAXMAXVAL );
  166.     break;
  167.  
  168.     case PAT_SQUIG:
  169.     squig( pixels, cols, rows, PPM_MAXMAXVAL );
  170.     break;
  171.  
  172.     case PAT_CAMO:
  173.     camo( pixels, cols, rows, PPM_MAXMAXVAL, 0 );
  174.     break;
  175.  
  176.     case PAT_ANTICAMO:
  177.     camo( pixels, cols, rows, PPM_MAXMAXVAL, 1 );
  178.     break;
  179.  
  180.     case PAT_TEST:
  181.     test( pixels, cols, rows, PPM_MAXMAXVAL );
  182.     break;
  183.  
  184.     default:
  185.     pm_error( "can't happen!" );
  186.     }
  187.  
  188.     /* All done, write it out. */
  189.     ppm_writeppm( stdout, pixels, cols, rows, PPM_MAXMAXVAL, 0 );
  190.     pm_close( stdout );
  191.  
  192.     exit( 0 );
  193.     }
  194.  
  195. #if __STDC__
  196. static pixel
  197. random_color( pixval maxval )
  198. #else /*__STDC__*/
  199. static pixel
  200. random_color( maxval )
  201.     pixval maxval;
  202. #endif /*__STDC__*/
  203.     {
  204.     pixel p;
  205.  
  206.     PPM_ASSIGN(
  207.     p, random() % ( maxval + 1 ), random() % ( maxval + 1 ),
  208.     random() % ( maxval + 1 ) );
  209.  
  210.     return p;
  211.     }
  212.  
  213. #define DARK_THRESH 0.25
  214.  
  215. #if __STDC__
  216. static pixel
  217. random_bright_color( pixval maxval )
  218. #else /*__STDC__*/
  219. static pixel
  220. random_bright_color( maxval )
  221.     pixval maxval;
  222. #endif /*__STDC__*/
  223.     {
  224.     pixel p;
  225.  
  226.     do
  227.     {
  228.     p = random_color( maxval );
  229.     }
  230.     while ( PPM_LUMIN( p ) <= maxval * DARK_THRESH );
  231.  
  232.     return p;
  233.     }
  234.  
  235. #if __STDC__
  236. static pixel
  237. random_dark_color( pixval maxval )
  238. #else /*__STDC__*/
  239. static pixel
  240. random_dark_color( maxval )
  241.     pixval maxval;
  242. #endif /*__STDC__*/
  243.     {
  244.     pixel p;
  245.  
  246.     do
  247.     {
  248.     p = random_color( maxval );
  249.     }
  250.     while ( PPM_LUMIN( p ) > maxval * DARK_THRESH );
  251.  
  252.     return p;
  253.     }
  254.  
  255. static pixel
  256. average_two_colors( p1, p2 )
  257. pixel p1, p2;
  258.     {
  259.     pixel p;
  260.  
  261.     PPM_ASSIGN(
  262.     p, ( (int) PPM_GETR(p1) + (int) PPM_GETR(p2) ) / 2,
  263.     ( (int) PPM_GETG(p1) + (int) PPM_GETG(p2) ) / 2,
  264.     ( (int) PPM_GETB(p1) + (int) PPM_GETB(p2) ) / 2 );
  265.  
  266.     return p;
  267.     }
  268.  
  269. #if __STDC__
  270. static void
  271. average_drawproc( pixel** pixels, int cols, int rows, pixval maxval, int col, int row, char* clientdata )
  272. #else /*__STDC__*/
  273. static void
  274. average_drawproc( pixels, cols, rows, maxval, col, row, clientdata )
  275.     pixel** pixels;
  276.     int cols, rows, col, row;
  277.     pixval maxval;
  278.     char* clientdata;
  279. #endif /*__STDC__*/
  280.     {
  281.     if ( col >= 0 && col < cols && row >= 0 && row < rows )
  282.     pixels[row][col] =
  283.         average_two_colors( pixels[row][col], *( (pixel*) clientdata ) );
  284.     }
  285.  
  286. /* Gingham stuff. */
  287.  
  288. #if __STDC__
  289. static void
  290. gingham2( pixel** pixels, int cols, int rows, pixval maxval )
  291. #else /*__STDC__*/
  292. static void
  293. gingham2( pixels, cols, rows, maxval )
  294.     pixel** pixels;
  295.     int cols, rows;
  296.     pixval maxval;
  297. #endif /*__STDC__*/
  298.     {
  299.     int colso2, rowso2;
  300.     pixel backcolor, forecolor;
  301.  
  302.     colso2 = cols / 2;
  303.     rowso2 = rows / 2;
  304.     backcolor = random_dark_color( maxval );
  305.     forecolor = random_bright_color( maxval );
  306.  
  307.     /* Warp. */
  308.     ppmd_filledrectangle(
  309.     pixels, cols, rows, maxval, 0, 0, colso2, rows, PPMD_NULLDRAWPROC,
  310.     (char*) &backcolor );
  311.     ppmd_filledrectangle(
  312.     pixels, cols, rows, maxval, colso2, 0, cols - colso2, rows,
  313.     PPMD_NULLDRAWPROC, (char*) &forecolor );
  314.  
  315.     /* Woof. */
  316.     ppmd_filledrectangle(
  317.     pixels, cols, rows, maxval, 0, 0, cols, rowso2, average_drawproc,
  318.     (char*) &backcolor );
  319.     ppmd_filledrectangle(
  320.     pixels, cols, rows, maxval, 0, rowso2, cols, rows - rowso2,
  321.     average_drawproc, (char*) &forecolor );
  322.     }
  323.  
  324. #if __STDC__
  325. static void
  326. gingham3( pixel** pixels, int cols, int rows, pixval maxval )
  327. #else /*__STDC__*/
  328. static void
  329. gingham3( pixels, cols, rows, maxval )
  330.     pixel** pixels;
  331.     int cols, rows;
  332.     pixval maxval;
  333. #endif /*__STDC__*/
  334.     {
  335.     int colso4, rowso4;
  336.     pixel backcolor, fore1color, fore2color;
  337.  
  338.     colso4 = cols / 4;
  339.     rowso4 = rows / 4;
  340.     backcolor = random_dark_color( maxval );
  341.     fore1color = random_bright_color( maxval );
  342.     fore2color = random_bright_color( maxval );
  343.  
  344.     /* Warp. */
  345.     ppmd_filledrectangle(
  346.     pixels, cols, rows, maxval, 0, 0, colso4, rows, PPMD_NULLDRAWPROC,
  347.     (char*) &backcolor );
  348.     ppmd_filledrectangle(
  349.     pixels, cols, rows, maxval, colso4, 0, colso4, rows, PPMD_NULLDRAWPROC,
  350.     (char*) &fore1color );
  351.     ppmd_filledrectangle(
  352.     pixels, cols, rows, maxval, 2 * colso4, 0, colso4, rows,
  353.     PPMD_NULLDRAWPROC, (char*) &fore2color );
  354.     ppmd_filledrectangle(
  355.     pixels, cols, rows, maxval, 3 * colso4, 0, cols - colso4, rows,
  356.     PPMD_NULLDRAWPROC, (char*) &fore1color );
  357.  
  358.     /* Woof. */
  359.     ppmd_filledrectangle(
  360.     pixels, cols, rows, maxval, 0, 0, cols, rowso4, average_drawproc,
  361.     (char*) &backcolor );
  362.     ppmd_filledrectangle(
  363.     pixels, cols, rows, maxval, 0, rowso4, cols, rowso4, average_drawproc,
  364.     (char*) &fore1color );
  365.     ppmd_filledrectangle(
  366.     pixels, cols, rows, maxval, 0, 2 * rowso4, cols, rowso4,
  367.     average_drawproc, (char*) &fore2color );
  368.     ppmd_filledrectangle(
  369.     pixels, cols, rows, maxval, 0, 3 * rowso4, cols, rows - rowso4,
  370.     average_drawproc, (char*) &fore1color );
  371.     }
  372.  
  373. #if __STDC__
  374. static void
  375. madras( pixel** pixels, int cols, int rows, pixval maxval )
  376. #else /*__STDC__*/
  377. static void
  378. madras( pixels, cols, rows, maxval )
  379.     pixel** pixels;
  380.     int cols, rows;
  381.     pixval maxval;
  382. #endif /*__STDC__*/
  383.     {
  384.     int cols2, rows2, cols3, rows3, cols12, rows12, cols6a, rows6a, cols6b,
  385.     rows6b;
  386.     pixel backcolor, fore1color, fore2color;
  387.  
  388.     cols2 = cols * 2 / 44;
  389.     rows2 = rows * 2 / 44;
  390.     cols3 = cols * 3 / 44;
  391.     rows3 = rows * 3 / 44;
  392.     cols12 = cols - 10 * cols2 - 4 * cols3;
  393.     rows12 = rows - 10 * rows2 - 4 * rows3;
  394.     cols6a = cols12 / 2;
  395.     rows6a = rows12 / 2;
  396.     cols6b = cols12 - cols6a;
  397.     rows6b = rows12 - rows6a;
  398.     backcolor = random_dark_color( maxval );
  399.     fore1color = random_bright_color( maxval );
  400.     fore2color = random_bright_color( maxval );
  401.  
  402.     /* Warp. */
  403.     ppmd_filledrectangle(
  404.     pixels, cols, rows, maxval, 0, 0, cols2, rows, PPMD_NULLDRAWPROC,
  405.     (char*) &backcolor );
  406.     ppmd_filledrectangle(
  407.     pixels, cols, rows, maxval, cols2, 0, cols3, rows, PPMD_NULLDRAWPROC,
  408.     (char*) &fore1color );
  409.     ppmd_filledrectangle(
  410.     pixels, cols, rows, maxval, cols2 + cols3, 0, cols2, rows,
  411.     PPMD_NULLDRAWPROC, (char*) &backcolor );
  412.     ppmd_filledrectangle(
  413.     pixels, cols, rows, maxval, 2 * cols2 + cols3, 0, cols2, rows,
  414.     PPMD_NULLDRAWPROC, (char*) &fore2color );
  415.     ppmd_filledrectangle(
  416.     pixels, cols, rows, maxval, 3 * cols2 + cols3, 0, cols2, rows,
  417.     PPMD_NULLDRAWPROC, (char*) &backcolor );
  418.     ppmd_filledrectangle(
  419.     pixels, cols, rows, maxval, 4 * cols2 + cols3, 0, cols6a, rows,
  420.     PPMD_NULLDRAWPROC, (char*) &fore1color );
  421.     ppmd_filledrectangle(
  422.     pixels, cols, rows, maxval, 4 * cols2 + cols3 + cols6a, 0, cols2, rows,
  423.     PPMD_NULLDRAWPROC, (char*) &backcolor );
  424.     ppmd_filledrectangle(
  425.     pixels, cols, rows, maxval, 5 * cols2 + cols3 + cols6a, 0, cols3, rows,
  426.     PPMD_NULLDRAWPROC, (char*) &fore2color );
  427.     ppmd_filledrectangle(
  428.     pixels, cols, rows, maxval, 5 * cols2 + 2 * cols3 + cols6a, 0, cols2,
  429.     rows, PPMD_NULLDRAWPROC, (char*) &backcolor );
  430.     ppmd_filledrectangle(
  431.     pixels, cols, rows, maxval, 6 * cols2 + 2 * cols3 + cols6a, 0, cols3,
  432.     rows, PPMD_NULLDRAWPROC, (char*) &fore2color );
  433.     ppmd_filledrectangle(
  434.     pixels, cols, rows, maxval, 6 * cols2 + 3 * cols3 + cols6a, 0, cols2,
  435.     rows, PPMD_NULLDRAWPROC, (char*) &backcolor );
  436.     ppmd_filledrectangle(
  437.     pixels, cols, rows, maxval, 7 * cols2 + 3 * cols3 + cols6a, 0, cols6b,
  438.     rows, PPMD_NULLDRAWPROC, (char*) &fore1color );
  439.     ppmd_filledrectangle(
  440.     pixels, cols, rows, maxval, 7 * cols2 + 3 * cols3 + cols6a + cols6b, 0,
  441.     cols2, rows, PPMD_NULLDRAWPROC, (char*) &backcolor );
  442.     ppmd_filledrectangle(
  443.     pixels, cols, rows, maxval, 8 * cols2 + 3 * cols3 + cols6a + cols6b, 0,
  444.     cols2, rows, PPMD_NULLDRAWPROC, (char*) &fore2color );
  445.     ppmd_filledrectangle(
  446.     pixels, cols, rows, maxval, 9 * cols2 + 3 * cols3 + cols6a + cols6b, 0,
  447.     cols2, rows, PPMD_NULLDRAWPROC, (char*) &backcolor );
  448.     ppmd_filledrectangle(
  449.     pixels, cols, rows, maxval, 10 * cols2 + 3 * cols3 + cols6a + cols6b, 0,
  450.     cols3, rows, PPMD_NULLDRAWPROC, (char*) &fore1color );
  451.  
  452.     /* Woof. */
  453.     ppmd_filledrectangle(
  454.     pixels, cols, rows, maxval, 0, 0, cols, rows2, average_drawproc,
  455.     (char*) &backcolor );
  456.     ppmd_filledrectangle(
  457.     pixels, cols, rows, maxval, 0, rows2, cols, rows3, average_drawproc,
  458.     (char*) &fore2color );
  459.     ppmd_filledrectangle(
  460.     pixels, cols, rows, maxval, 0, rows2 + rows3, cols, rows2,
  461.     average_drawproc, (char*) &backcolor );
  462.     ppmd_filledrectangle(
  463.     pixels, cols, rows, maxval, 0, 2 * rows2 + rows3, cols, rows2,
  464.     average_drawproc, (char*) &fore1color );
  465.     ppmd_filledrectangle(
  466.     pixels, cols, rows, maxval, 0, 3 * rows2 + rows3, cols, rows2,
  467.     average_drawproc, (char*) &backcolor );
  468.     ppmd_filledrectangle(
  469.     pixels, cols, rows, maxval, 0, 4 * rows2 + rows3, cols, rows6a,
  470.     average_drawproc, (char*) &fore2color );
  471.     ppmd_filledrectangle(
  472.     pixels, cols, rows, maxval, 0, 4 * rows2 + rows3 + rows6a, cols, rows2,
  473.     average_drawproc, (char*) &backcolor );
  474.     ppmd_filledrectangle(
  475.     pixels, cols, rows, maxval, 0, 5 * rows2 + rows3 + rows6a, cols, rows3,
  476.     average_drawproc, (char*) &fore1color );
  477.     ppmd_filledrectangle(
  478.     pixels, cols, rows, maxval, 0, 5 * rows2 + 2 * rows3 + rows6a, cols,
  479.     rows2, average_drawproc, (char*) &backcolor );
  480.     ppmd_filledrectangle(
  481.     pixels, cols, rows, maxval, 0, 6 * rows2 + 2 * rows3 + rows6a, cols,
  482.     rows3, average_drawproc, (char*) &fore1color );
  483.     ppmd_filledrectangle(
  484.     pixels, cols, rows, maxval, 0, 6 * rows2 + 3 * rows3 + rows6a, cols,
  485.     rows2, average_drawproc, (char*) &backcolor );
  486.     ppmd_filledrectangle(
  487.     pixels, cols, rows, maxval, 0, 7 * rows2 + 3 * rows3 + rows6a, cols,
  488.     rows6b, average_drawproc, (char*) &fore2color );
  489.     ppmd_filledrectangle(
  490.     pixels, cols, rows, maxval, 0, 7 * rows2 + 3 * rows3 + rows6a + rows6b,
  491.     cols, rows2, average_drawproc, (char*) &backcolor );
  492.     ppmd_filledrectangle(
  493.     pixels, cols, rows, maxval, 0, 8 * rows2 + 3 * rows3 + rows6a + rows6b,
  494.     cols, rows2, average_drawproc, (char*) &fore1color );
  495.     ppmd_filledrectangle(
  496.     pixels, cols, rows, maxval, 0, 9 * rows2 + 3 * rows3 + rows6a + rows6b,
  497.     cols, rows2, average_drawproc, (char*) &backcolor );
  498.     ppmd_filledrectangle(
  499.     pixels, cols, rows, maxval, 0, 10 * rows2 + 3 * rows3 + rows6a + rows6b,
  500.     cols, rows3, average_drawproc, (char*) &fore2color );
  501.     }
  502.  
  503. #if __STDC__
  504. static void
  505. tartan( pixel** pixels, int cols, int rows, pixval maxval )
  506. #else /*__STDC__*/
  507. static void
  508. tartan( pixels, cols, rows, maxval )
  509.     pixel** pixels;
  510.     int cols, rows;
  511.     pixval maxval;
  512. #endif /*__STDC__*/
  513.     {
  514.     int cols1, rows1, cols3, rows3, cols10, rows10, cols5a, rows5a, cols5b,
  515.     rows5b;
  516.     pixel backcolor, fore1color, fore2color;
  517.  
  518.     cols1 = cols / 22;
  519.     rows1 = rows / 22;
  520.     cols3 = cols * 3 / 22;
  521.     rows3 = rows * 3 / 22;
  522.     cols10 = cols - 3 * cols1 - 3 * cols3;
  523.     rows10 = rows - 3 * rows1 - 3 * rows3;
  524.     cols5a = cols10 / 2;
  525.     rows5a = rows10 / 2;
  526.     cols5b = cols10 - cols5a;
  527.     rows5b = rows10 - rows5a;
  528.     backcolor = random_dark_color( maxval );
  529.     fore1color = random_bright_color( maxval );
  530.     fore2color = random_bright_color( maxval );
  531.  
  532.     /* Warp. */
  533.     ppmd_filledrectangle(
  534.     pixels, cols, rows, maxval, 0, 0, cols5a, rows, PPMD_NULLDRAWPROC,
  535.     (char*) &backcolor );
  536.     ppmd_filledrectangle(
  537.     pixels, cols, rows, maxval, cols5a, 0, cols1, rows, PPMD_NULLDRAWPROC,
  538.     (char*) &fore1color );
  539.     ppmd_filledrectangle(
  540.     pixels, cols, rows, maxval, cols5a + cols1, 0, cols5b, rows,
  541.     PPMD_NULLDRAWPROC, (char*) &backcolor );
  542.     ppmd_filledrectangle(
  543.     pixels, cols, rows, maxval, cols10 + cols1, 0, cols3, rows,
  544.     PPMD_NULLDRAWPROC, (char*) &fore2color );
  545.     ppmd_filledrectangle(
  546.     pixels, cols, rows, maxval, cols10 + cols1 + cols3, 0, cols1, rows,
  547.     PPMD_NULLDRAWPROC, (char*) &backcolor );
  548.     ppmd_filledrectangle(
  549.     pixels, cols, rows, maxval, cols10 + 2 * cols1 + cols3, 0, cols3, rows,
  550.     PPMD_NULLDRAWPROC, (char*) &fore2color );
  551.     ppmd_filledrectangle(
  552.     pixels, cols, rows, maxval, cols10 + 2 * cols1 + 2 * cols3, 0, cols1,
  553.     rows, PPMD_NULLDRAWPROC, (char*) &backcolor );
  554.     ppmd_filledrectangle(
  555.     pixels, cols, rows, maxval, cols10 + 3 * cols1 + 2 * cols3, 0, cols3,
  556.     rows, PPMD_NULLDRAWPROC, (char*) &fore2color );
  557.  
  558.     /* Woof. */
  559.     ppmd_filledrectangle(
  560.     pixels, cols, rows, maxval, 0, 0, cols, rows5a, average_drawproc,
  561.     (char*) &backcolor );
  562.     ppmd_filledrectangle(
  563.     pixels, cols, rows, maxval, 0, rows5a, cols, rows1, average_drawproc,
  564.     (char*) &fore1color );
  565.     ppmd_filledrectangle(
  566.     pixels, cols, rows, maxval, 0, rows5a + rows1, cols, rows5b,
  567.     average_drawproc, (char*) &backcolor );
  568.     ppmd_filledrectangle(
  569.     pixels, cols, rows, maxval, 0, rows10 + rows1, cols, rows3,
  570.     average_drawproc, (char*) &fore2color );
  571.     ppmd_filledrectangle(
  572.     pixels, cols, rows, maxval, 0, rows10 + rows1 + rows3, cols, rows1,
  573.     average_drawproc, (char*) &backcolor );
  574.     ppmd_filledrectangle(
  575.     pixels, cols, rows, maxval, 0, rows10 + 2 * rows1 + rows3, cols, rows3,
  576.     average_drawproc, (char*) &fore2color );
  577.     ppmd_filledrectangle(
  578.     pixels, cols, rows, maxval, 0, rows10 + 2 * rows1 + 2 * rows3, cols,
  579.     rows1, average_drawproc, (char*) &backcolor );
  580.     ppmd_filledrectangle(
  581.     pixels, cols, rows, maxval, 0, rows10 + 3 * rows1 + 2 * rows3, cols,
  582.     rows3, average_drawproc, (char*) &fore2color );
  583.     }
  584.  
  585. /* Poles stuff. */
  586.  
  587. #define MAXPOLES 500
  588.  
  589. #if __STDC__
  590. static void
  591. poles( pixel** pixels, int cols, int rows, pixval maxval )
  592. #else /*__STDC__*/
  593. static void
  594. poles( pixels, cols, rows, maxval )
  595.     pixel** pixels;
  596.     int cols, rows;
  597.     pixval maxval;
  598. #endif /*__STDC__*/
  599.     {
  600.     int poles, i, xs[MAXPOLES], ys[MAXPOLES], col, row;
  601.     pixel colors[MAXPOLES];
  602.  
  603.     poles = cols * rows / 30000;
  604.  
  605.     /* Place and color poles randomly. */
  606.     for ( i = 0; i < poles; ++i )
  607.     {
  608.     xs[i] = random() % cols;
  609.     ys[i] = random() % rows;
  610.     colors[i] = random_bright_color( maxval );
  611.     }
  612.  
  613.     /* Now interpolate points. */
  614.     for ( row = 0; row < rows; ++row )
  615.     for ( col = 0; col < cols; ++col )
  616.         {
  617.         register long dist1, dist2, newdist, r, g, b;
  618.         pixel color1, color2;
  619.  
  620.         /* Find two closest poles. */
  621.         dist1 = dist2 = 2000000000;
  622.         for ( i = 0; i < poles; ++i )
  623.         {
  624.         newdist = ( col - xs[i] ) * ( col - xs[i] ) +
  625.               ( row - ys[i] ) * ( row - ys[i] );
  626.         if ( newdist < dist1 )
  627.             {
  628.             dist1 = newdist;
  629.             color1 = colors[i];
  630.             }
  631.         else if ( newdist < dist2 )
  632.             {
  633.             dist2 = newdist;
  634.             color2 = colors[i];
  635.             }
  636.         }
  637.  
  638.         /* And assign interpolated color. */
  639.         newdist = dist1 + dist2;
  640.         r = PPM_GETR(color1)*dist2/newdist + PPM_GETR(color2)*dist1/newdist;
  641.         g = PPM_GETG(color1)*dist2/newdist + PPM_GETG(color2)*dist1/newdist;
  642.         b = PPM_GETB(color1)*dist2/newdist + PPM_GETB(color2)*dist1/newdist;
  643.         PPM_ASSIGN( pixels[row][col], r, g, b );
  644.         }
  645.     }
  646.  
  647. /* Squig stuff. */
  648.  
  649. #define SQUIGS 5
  650. #define SQ_POINTS 7
  651. #define SQ_MAXCIRCLE_POINTS 5000
  652.  
  653. static int sq_radius, sq_circlecount;
  654. static pixel sq_colors[SQ_MAXCIRCLE_POINTS];
  655. static int sq_xoffs[SQ_MAXCIRCLE_POINTS], sq_yoffs[SQ_MAXCIRCLE_POINTS];
  656.  
  657. #if __STDC__
  658. static void
  659. sq_measurecircle_drawproc( pixel** pixels, int cols, int rows, pixval maxval, int col, int row, char* clientdata )
  660. #else /*__STDC__*/
  661. static void
  662. sq_measurecircle_drawproc( pixels, cols, rows, maxval, col, row, clientdata )
  663.     pixel** pixels;
  664.     int cols, rows, col, row;
  665.     pixval maxval;
  666.     char* clientdata;
  667. #endif /*__STDC__*/
  668.     {
  669.     sq_xoffs[sq_circlecount] = col;
  670.     sq_yoffs[sq_circlecount] = row;
  671.     ++sq_circlecount;
  672.     }
  673.  
  674. #if __STDC__
  675. static void
  676. sq_rainbowcircle_drawproc( pixel** pixels, int cols, int rows, pixval maxval, int col, int row, char* clientdata )
  677. #else /*__STDC__*/
  678. static void
  679. sq_rainbowcircle_drawproc( pixels, cols, rows, maxval, col, row, clientdata )
  680.     pixel** pixels;
  681.     int cols, rows, col, row;
  682.     pixval maxval;
  683.     char* clientdata;
  684. #endif /*__STDC__*/
  685.     {
  686.     int i;
  687.  
  688.     for ( i = 0; i < sq_circlecount; ++i )
  689.     ppmd_point_drawproc(
  690.         pixels, cols, rows, maxval, col + sq_xoffs[i], row + sq_yoffs[i],
  691.         (char*) &(sq_colors[i]) );
  692.     }
  693.  
  694. #if __STDC__
  695. static void
  696. squig( pixel** pixels, int cols, int rows, pixval maxval )
  697. #else /*__STDC__*/
  698. static void
  699. squig( pixels, cols, rows, maxval )
  700.     pixel** pixels;
  701.     int cols, rows;
  702.     pixval maxval;
  703. #endif /*__STDC__*/
  704.     {
  705.     pixel color;
  706.     int i, j, xc[SQ_POINTS], yc[SQ_POINTS], x0, y0, x1, y1, x2, y2, x3, y3;
  707.  
  708.     /* Clear image to black. */
  709.     PPM_ASSIGN( color, 0, 0, 0 );
  710.     ppmd_filledrectangle(
  711.     pixels, cols, rows, maxval, 0, 0, cols, rows, PPMD_NULLDRAWPROC,
  712.     (char*) &color );
  713.  
  714.     /* Draw the squigs. */
  715.     (void) ppmd_setlinetype( PPMD_LINETYPE_NODIAGS );
  716.     (void) ppmd_setlineclip( 0 );
  717.     for ( i = SQUIGS; i > 0; --i )
  718.     {
  719.     /* Measure circle. */
  720.     sq_radius = ( cols + rows ) / 2 / ( 25 + i * 2 );
  721.     sq_circlecount = 0;
  722.     ppmd_circle(
  723.         pixels, cols, rows, maxval, 0, 0, sq_radius,
  724.         sq_measurecircle_drawproc, 0 );
  725.     sq_assign_colors( sq_circlecount, maxval, sq_colors );
  726.  
  727.     /* Choose wrap-around point. */
  728.     switch ( random() % 4 )
  729.         {
  730.         case 0:
  731.         x1 = random() % cols;
  732.         y1 = 0;
  733.         if ( x1 < cols / 2 )
  734.         xc[0] = random() % ( x1 * 2 );
  735.         else
  736.         xc[0] = cols - 1 - random() % ( ( cols - x1 ) * 2 );
  737.         yc[0] = random() % rows;
  738.         x2 = x1;
  739.         y2 = rows - 1;
  740.         xc[SQ_POINTS - 1] = 2 * x2 - xc[0];
  741.         yc[SQ_POINTS - 1] = y2 - yc[0];
  742.         x0 = xc[SQ_POINTS - 1];
  743.         y0 = yc[SQ_POINTS - 1] - rows;
  744.         x3 = xc[0];
  745.         y3 = yc[0] + rows;
  746.         break;
  747.  
  748.         case 1:
  749.         x2 = random() % cols;
  750.         y2 = 0;
  751.         if ( x2 < cols / 2 )
  752.         xc[SQ_POINTS - 1] = random() % ( x2 * 2 );
  753.         else
  754.         xc[SQ_POINTS - 1] = cols - 1 - random() % ( ( cols - x2 ) * 2 );
  755.         yc[SQ_POINTS - 1] = random() % rows;
  756.         x1 = x2;
  757.         y1 = rows - 1;
  758.         xc[0] = 2 * x1 - xc[SQ_POINTS - 1];
  759.         yc[0] = y1 - yc[SQ_POINTS - 1];
  760.         x0 = xc[SQ_POINTS - 1];
  761.         y0 = yc[SQ_POINTS - 1] + rows;
  762.         x3 = xc[0];
  763.         y3 = yc[0] - rows;
  764.         break;
  765.  
  766.         case 2:
  767.         x1 = 0;
  768.         y1 = random() % rows;
  769.         xc[0] = random() % cols;
  770.         if ( y1 < rows / 2 )
  771.         yc[0] = random() % ( y1 * 2 );
  772.         else
  773.         yc[0] = rows - 1 - random() % ( ( rows - y1 ) * 2 );
  774.         x2 = cols - 1;
  775.         y2 = y1;
  776.         xc[SQ_POINTS - 1] = x2 - xc[0];
  777.         yc[SQ_POINTS - 1] = 2 * y2 - yc[0];
  778.         x0 = xc[SQ_POINTS - 1] - cols;
  779.         y0 = yc[SQ_POINTS - 1];
  780.         x3 = xc[0] + cols;
  781.         y3 = yc[0];
  782.         break;
  783.  
  784.         case 3:
  785.         x2 = 0;
  786.         y2 = random() % rows;
  787.         xc[SQ_POINTS - 1] = random() % cols;
  788.         if ( y2 < rows / 2 )
  789.         yc[SQ_POINTS - 1] = random() % ( y2 * 2 );
  790.         else
  791.         yc[SQ_POINTS - 1] = rows - 1 - random() % ( ( rows - y2 ) * 2 );
  792.         x1 = cols - 1;
  793.         y1 = y2;
  794.         xc[0] = x1 - xc[SQ_POINTS - 1];
  795.         yc[0] = 2 * y1 - yc[SQ_POINTS - 1];
  796.         x0 = xc[SQ_POINTS - 1] + cols;
  797.         y0 = yc[SQ_POINTS - 1];
  798.         x3 = xc[0] - cols;
  799.         y3 = yc[0];
  800.         break;
  801.         }
  802.  
  803.     for ( j = 1; j < SQ_POINTS - 1; ++j )
  804.         {
  805.         xc[j] = ( random() % ( cols - 2 * sq_radius ) ) + sq_radius;
  806.         yc[j] = ( random() % ( rows - 2 * sq_radius ) ) + sq_radius;
  807.         }
  808.  
  809.     ppmd_line(
  810.         pixels, cols, rows, maxval, x0, y0, x1, y1,
  811.         sq_rainbowcircle_drawproc, 0 );
  812.     ppmd_polyspline(
  813.         pixels, cols, rows, maxval, x1, y1, SQ_POINTS, xc, yc, x2, y2,
  814.         sq_rainbowcircle_drawproc, 0 );
  815.     ppmd_line(
  816.         pixels, cols, rows, maxval, x2, y2, x3, y3,
  817.         sq_rainbowcircle_drawproc, 0 );
  818.     }
  819.     }
  820.  
  821. #if __STDC__
  822. static void
  823. sq_assign_colors( int circlecount, pixval maxval, pixel* colors )
  824. #else /*__STDC__*/
  825. static void
  826. sq_assign_colors( circlecount, maxval, colors )
  827.     int circlecount;
  828.     pixval maxval;
  829.     pixel* colors;
  830. #endif /*__STDC__*/
  831.     {
  832.     pixel rc1, rc2, rc3;
  833.     float cco3;
  834.     int i;
  835.  
  836.     rc1 = random_bright_color( maxval );
  837.     rc2 = random_bright_color( maxval );
  838.     rc3 = random_bright_color( maxval );
  839.     cco3 = ( circlecount - 1 ) / 3.0;
  840.  
  841.     for ( i = 0; i < circlecount ; ++i )
  842.     {
  843.     if ( i < cco3 )
  844.         PPM_ASSIGN(
  845.         colors[i],
  846.         (float) PPM_GETR(rc1) +
  847.             ( (float) PPM_GETR(rc2) - (float) PPM_GETR(rc1) ) *
  848.             (float) i / cco3,
  849.         (float) PPM_GETG(rc1) +
  850.             ( (float) PPM_GETG(rc2) - (float) PPM_GETG(rc1) ) *
  851.             (float) i / cco3,
  852.         (float) PPM_GETB(rc1) +
  853.             ( (float) PPM_GETB(rc2) - (float) PPM_GETB(rc1) ) *
  854.             (float) i / cco3 );
  855.     else if ( i < 2.0 * cco3 )
  856.         PPM_ASSIGN(
  857.         colors[i],
  858.         (float) PPM_GETR(rc2) +
  859.             ( (float) PPM_GETR(rc3) - (float) PPM_GETR(rc2) ) *
  860.             ( (float) i / cco3 - 1.0 ),
  861.         (float) PPM_GETG(rc2) +
  862.             ( (float) PPM_GETG(rc3) - (float) PPM_GETG(rc2) ) *
  863.             ( (float) i / cco3 - 1.0 ),
  864.         (float) PPM_GETB(rc2) +
  865.             ( (float) PPM_GETB(rc3) - (float) PPM_GETB(rc2) ) *
  866.             ( (float) i / cco3 - 1.0 ) );
  867.     else
  868.         PPM_ASSIGN(
  869.         colors[i],
  870.         (float) PPM_GETR(rc3) +
  871.             ( (float) PPM_GETR(rc1) - (float) PPM_GETR(rc3) ) *
  872.             ( (float) i / cco3 - 2.0 ),
  873.         (float) PPM_GETG(rc3) +
  874.             ( (float) PPM_GETG(rc1) - (float) PPM_GETG(rc3) ) *
  875.             ( (float) i / cco3 - 2.0 ),
  876.         (float) PPM_GETB(rc3) +
  877.             ( (float) PPM_GETB(rc1) - (float) PPM_GETB(rc3) ) *
  878.             ( (float) i / cco3 - 2.0 ) );
  879.     }
  880.     }
  881.  
  882. /* Camouflage stuff. */
  883.  
  884. #if __STDC__
  885. static pixel
  886. random_camo_color( pixval maxval )
  887. #else /*__STDC__*/
  888. static pixel
  889. random_camo_color( maxval )
  890.     pixval maxval;
  891. #endif /*__STDC__*/
  892.     {
  893.     int v1, v2, v3;
  894.     pixel p;
  895.  
  896.     v1 = ( (int) maxval + 1 ) / 8;
  897.     v2 = ( (int) maxval + 1 ) / 4;
  898.     v3 = ( (int) maxval + 1 ) / 2;
  899.  
  900.     switch ( random() % 10 )
  901.     {
  902.     case 0:    case 1: case 2: /* light brown */
  903.     PPM_ASSIGN(
  904.         p, random() % v3 + v3, random() % v3 + v2, random() % v3 + v2 );
  905.     break;
  906.  
  907.     case 3:    case 4: case 5: /* dark green */
  908.     PPM_ASSIGN( p, random() % v2, random() % v2 + 3 * v1, random() % v2 );
  909.     break;
  910.  
  911.     case 6:    case 7: /* brown */
  912.     PPM_ASSIGN( p, random() % v2 + v2, random() % v2, random() % v2 );
  913.     break;
  914.  
  915.     case 8:    case 9: /* dark brown */
  916.     PPM_ASSIGN( p, random() % v1 + v1, random() % v1, random() % v1 );
  917.     break;
  918.     }
  919.  
  920.     return p;
  921.     }
  922.  
  923. #if __STDC__
  924. static pixel
  925. random_anticamo_color( pixval maxval )
  926. #else /*__STDC__*/
  927. static pixel
  928. random_anticamo_color( maxval )
  929.     pixval maxval;
  930. #endif /*__STDC__*/
  931.     {
  932.     int v1, v2, v3;
  933.     pixel p;
  934.  
  935.     v1 = ( (int) maxval + 1 ) / 4;
  936.     v2 = ( (int) maxval + 1 ) / 2;
  937.     v3 = 3 * v1;
  938.  
  939.     switch ( random() % 15 )
  940.     {
  941.     case 0: case 1:
  942.     PPM_ASSIGN( p, random() % v1 + v3, random() % v2, random() % v2 );
  943.     break;
  944.  
  945.     case 2: case 3:
  946.     PPM_ASSIGN( p, random() % v2, random() % v1 + v3, random() % v2 );
  947.     break;
  948.  
  949.     case 4: case 5:
  950.     PPM_ASSIGN( p, random() % v2, random() % v2, random() % v1 + v3 );
  951.     break;
  952.  
  953.     case 6: case 7: case 8:
  954.     PPM_ASSIGN( p, random() % v2, random() % v1 + v3, random() % v1 + v3 );
  955.     break;
  956.  
  957.     case 9: case 10: case 11:
  958.     PPM_ASSIGN( p, random() % v1 + v3, random() % v2, random() % v1 + v3 );
  959.     break;
  960.  
  961.     case 12: case 13: case 14:
  962.     PPM_ASSIGN( p, random() % v1 + v3, random() % v1 + v3, random() % v2 );
  963.     break;
  964.  
  965.     }
  966.  
  967.     return p;
  968.     }
  969.  
  970. static float
  971. rnduni( )
  972.     {
  973.     return random() % 32767 / 32767.0;
  974.     }
  975.  
  976. #define BLOBRAD 50
  977.  
  978. #define MIN_POINTS 7
  979. #define MAX_POINTS 13
  980.  
  981. #define MIN_ELLIPSE_FACTOR 0.5
  982. #define MAX_ELLIPSE_FACTOR 2.0
  983.  
  984. #define MIN_POINT_FACTOR 0.5
  985. #define MAX_POINT_FACTOR 2.0
  986.  
  987. #if __STDC__
  988. static void
  989. camo( pixel** pixels, int cols, int rows, pixval maxval, int antiflag )
  990. #else /*__STDC__*/
  991. static void
  992. camo( pixels, cols, rows, maxval, antiflag )
  993.     pixel** pixels;
  994.     int cols, rows, antiflag;
  995.     pixval maxval;
  996. #endif /*__STDC__*/
  997.     {
  998.     pixel color;
  999.     int n, i, cx, cy;
  1000.     char* fh;
  1001.  
  1002.     /* Clear background. */
  1003.     if ( antiflag )
  1004.     color = random_anticamo_color( maxval );
  1005.     else
  1006.     color = random_camo_color( maxval );
  1007.     ppmd_filledrectangle(
  1008.     pixels, cols, rows, maxval, 0, 0, cols, rows, PPMD_NULLDRAWPROC,
  1009.     (char*) &color );
  1010.  
  1011.     n = ( rows * cols ) / ( BLOBRAD * BLOBRAD ) * 5;
  1012.     for ( i = 0; i < n; ++i )
  1013.     {
  1014.     int points, p, xs[MAX_POINTS], ys[MAX_POINTS], x0, y0;
  1015.     float a, b, c, theta, tang, tx, ty;
  1016.  
  1017.     cx = random() % cols;
  1018.     cy = random() % rows;
  1019.  
  1020.     points = random() % ( MAX_POINTS - MIN_POINTS + 1 ) + MIN_POINTS;
  1021.     a = rnduni() * ( MAX_ELLIPSE_FACTOR - MIN_ELLIPSE_FACTOR ) +
  1022.         MIN_ELLIPSE_FACTOR;
  1023.     b = rnduni() * ( MAX_ELLIPSE_FACTOR - MIN_ELLIPSE_FACTOR ) +
  1024.         MIN_ELLIPSE_FACTOR;
  1025.     theta = rnduni() * 2.0 * M_PI;
  1026.     for ( p = 0; p < points; ++p )
  1027.         {
  1028.         tx = a * sin( p * 2.0 * M_PI / points );
  1029.         ty = b * cos( p * 2.0 * M_PI / points );
  1030.         tang = atan2( ty, tx ) + theta;
  1031.         c = rnduni() * ( MAX_POINT_FACTOR - MIN_POINT_FACTOR ) +
  1032.         MIN_POINT_FACTOR;
  1033.         xs[p] = cx + BLOBRAD * c * sin( tang );
  1034.         ys[p] = cy + BLOBRAD * c * cos( tang );
  1035.         }
  1036.     x0 = ( xs[0] + xs[points - 1] ) / 2;
  1037.     y0 = ( ys[0] + ys[points - 1] ) / 2;
  1038.  
  1039.     fh = ppmd_fill_init();
  1040.  
  1041.     ppmd_polyspline(
  1042.         pixels, cols, rows, maxval, x0, y0, points, xs, ys, x0, y0,
  1043.         ppmd_fill_drawproc, fh );
  1044.  
  1045.     if ( antiflag )
  1046.         color = random_anticamo_color( maxval );
  1047.     else
  1048.         color = random_camo_color( maxval );
  1049.     ppmd_fill( pixels, cols, rows, maxval, fh, PPMD_NULLDRAWPROC, (char*) &color );
  1050.     }
  1051.     }
  1052.  
  1053. /* Test pattern.  Just a place to put ppmdraw exercises. */
  1054.  
  1055. #if __STDC__
  1056. static void
  1057. test( pixel** pixels, int cols, int rows, pixval maxval )
  1058. #else /*__STDC__*/
  1059. static void
  1060. test( pixels, cols, rows, maxval )
  1061.     pixel** pixels;
  1062.     int cols, rows;
  1063.     pixval maxval;
  1064. #endif /*__STDC__*/
  1065.     {
  1066.     pixel color;
  1067.     char* fh;
  1068.  
  1069.     /* Clear image to black. */
  1070.     PPM_ASSIGN( color, 0, 0, 0 );
  1071.     ppmd_filledrectangle(
  1072.     pixels, cols, rows, maxval, 0, 0, cols, rows, PPMD_NULLDRAWPROC,
  1073.     (char*) &color );
  1074.  
  1075.     fh = ppmd_fill_init();
  1076.  
  1077.     ppmd_line( pixels, cols, rows, maxval, cols/8, rows/8, cols/2, rows/4, ppmd_fill_drawproc, fh );
  1078.     ppmd_line( pixels, cols, rows, maxval, cols/2, rows/4, cols-cols/8, rows/8, ppmd_fill_drawproc, fh );
  1079.     ppmd_line( pixels, cols, rows, maxval, cols-cols/8, rows/8, cols/2, rows/2, ppmd_fill_drawproc, fh );
  1080.     ppmd_spline3( pixels, cols, rows, maxval, cols/2, rows/2, cols/2-cols/16, rows/2-rows/10, cols/2-cols/8, rows/2, ppmd_fill_drawproc, fh );
  1081.     ppmd_spline3( pixels, cols, rows, maxval, cols/2-cols/8, rows/2, cols/4+cols/16, rows/2+rows/10, cols/4, rows/2, ppmd_fill_drawproc, fh );
  1082.     ppmd_line( pixels, cols, rows, maxval, cols/4, rows/2, cols/8, rows/2, ppmd_fill_drawproc, fh );
  1083.     ppmd_line( pixels, cols, rows, maxval, cols/8, rows/2, cols/8, rows/8, ppmd_fill_drawproc, fh );
  1084.  
  1085.     PPM_ASSIGN( color, maxval, maxval, maxval );
  1086.     ppmd_fill( pixels, cols, rows, maxval, fh, PPMD_NULLDRAWPROC, (char*) &color );
  1087.     }
  1088.